 /*******************************************************************************
  * Copyright (c) 2000, 2004 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Common Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/cpl-v10.html
  *
  * Contributors:
  * IBM Corporation - initial API and implementation
  *******************************************************************************/

 package org.eclipse.ui.internal.commands;

 import java.io.IOException ;
 import java.text.Collator ;
 import java.text.MessageFormat ;
 import java.util.ArrayList ;
 import java.util.Collection ;
 import java.util.Collections ;
 import java.util.HashMap ;
 import java.util.HashSet ;
 import java.util.Iterator ;
 import java.util.List ;
 import java.util.Map ;
 import java.util.ResourceBundle ;
 import java.util.Set ;
 import java.util.SortedMap ;
 import java.util.TreeMap ;
 import java.util.TreeSet ;

 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.MessageDialog;
 import org.eclipse.jface.preference.FieldEditor;
 import org.eclipse.jface.preference.IPreferenceStore;
 import org.eclipse.jface.preference.IntegerFieldEditor;
 import org.eclipse.jface.preference.StringFieldEditor;
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.FocusEvent;
 import org.eclipse.swt.events.FocusListener;
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
 import org.eclipse.swt.events.MouseAdapter;
 import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.Color;
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Group;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;
 import org.eclipse.swt.widgets.TabFolder;
 import org.eclipse.swt.widgets.TabItem;
 import org.eclipse.swt.widgets.Table;
 import org.eclipse.swt.widgets.TableColumn;
 import org.eclipse.swt.widgets.TableItem;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.IWorkbench;
 import org.eclipse.ui.IWorkbenchPreferencePage;
 import org.eclipse.ui.PlatformUI;
 import org.eclipse.ui.commands.ICategory;
 import org.eclipse.ui.commands.ICommand;
 import org.eclipse.ui.commands.IKeyConfiguration;
 import org.eclipse.ui.contexts.IContext;
 import org.eclipse.ui.contexts.IContextManager;
 import org.eclipse.ui.contexts.IWorkbenchContextSupport;
 import org.eclipse.ui.internal.IPreferenceConstants;
 import org.eclipse.ui.internal.IWorkbenchConstants;
 import org.eclipse.ui.internal.WorkbenchPlugin;
 import org.eclipse.ui.internal.keys.KeySequenceText;
 import org.eclipse.ui.internal.util.Util;
 import org.eclipse.ui.keys.KeySequence;
 import org.eclipse.ui.keys.KeyStroke;

 public class KeysPreferencePage extends
         org.eclipse.jface.preference.PreferencePage implements
         IWorkbenchPreferencePage {

     private final static class CommandAssignment implements Comparable {

         private KeySequenceBindingNode.Assignment assignment;

         private String contextId;

         private KeySequence keySequence;

         public int compareTo(Object object) {
             CommandAssignment castedObject = (CommandAssignment) object;
             int compareTo = Util.compare(contextId, castedObject.contextId);

             if (compareTo == 0) {
                 compareTo = Util.compare(keySequence, castedObject.keySequence);

                 if (compareTo == 0)
                         compareTo = Util.compare(assignment,
                                 castedObject.assignment);
             }

             return compareTo;
         }

         public boolean equals(Object object) {
             if (!(object instanceof CommandAssignment)) return false;

             CommandAssignment castedObject = (CommandAssignment) object;
             boolean equals = true;
             equals &= Util.equals(assignment, castedObject.assignment);
             equals &= Util.equals(contextId, castedObject.contextId);
             equals &= Util.equals(keySequence, castedObject.keySequence);
             return equals;
         }
     }

     private final static class KeySequenceAssignment implements Comparable {

         private KeySequenceBindingNode.Assignment assignment;

         private String contextId;

         public int compareTo(Object object) {
             KeySequenceAssignment castedObject = (KeySequenceAssignment) object;
             int compareTo = Util.compare(contextId, castedObject.contextId);

             if (compareTo == 0)
                     compareTo = Util.compare(assignment,
                             castedObject.assignment);

             return compareTo;
         }

         public boolean equals(Object object) {
             if (!(object instanceof CommandAssignment)) return false;

             KeySequenceAssignment castedObject = (KeySequenceAssignment) object;
             boolean equals = true;
             equals &= Util.equals(assignment, castedObject.assignment);
             equals &= Util.equals(contextId, castedObject.contextId);
             return equals;
         }
     }

     private final static int DIFFERENCE_ADD = 0;

     private final static int DIFFERENCE_CHANGE = 1;

     private final static int DIFFERENCE_MINUS = 2;

     private final static int DIFFERENCE_NONE = 3;

     private final static Image IMAGE_BLANK = ImageFactory.getImage("blank"); //$NON-NLS-1$

     private final static Image IMAGE_CHANGE = ImageFactory.getImage("change"); //$NON-NLS-1$

     private final static Image IMAGE_MINUS = ImageFactory.getImage("minus"); //$NON-NLS-1$

     private final static Image IMAGE_PLUS = ImageFactory.getImage("plus"); //$NON-NLS-1$

     private final static ResourceBundle RESOURCE_BUNDLE = ResourceBundle
             .getBundle(KeysPreferencePage.class.getName());

     private Map assignmentsByContextIdByKeySequence;

     private Button buttonAdd;

     private Button buttonAddKey;

     private Button buttonRemove;

     private Button buttonRestore;

     private Map categoryIdsByUniqueName;

     private Map categoryUniqueNamesById;

     private Button checkBoxMultiKeyAssist;

     private Combo comboCategory;

     private Combo comboCommand;

     private Combo comboContext;

     private Combo comboKeyConfiguration;

     private Set commandAssignments;

     private Map commandIdsByCategoryId;

     private Map commandIdsByUniqueName;

     private MutableCommandManager commandManager;

     private Map commandUniqueNamesById;

     private Map contextIdsByUniqueName;

     private IContextManager contextManager;

     private Map contextUniqueNamesById;

     private Group groupCommand;

     private Group groupKeySequence;

     private Map keyConfigurationIdsByUniqueName;

     private Map keyConfigurationUniqueNamesById;

     private Set keySequenceAssignments;

     private Label labelAssignmentsForCommand;

     private Label labelAssignmentsForKeySequence;

     private Label labelCategory;

     private Label labelCommand;

     private Label labelContext;

     private Label labelContextExtends;

     private Label labelKeyConfiguration;

     private Label labelKeyConfigurationExtends;

     private Label labelKeySequence;

     private Menu menuButtonAddKey;

     private Color minusColour;

     private Table tableAssignmentsForCommand;

     private Table tableAssignmentsForKeySequence;

     private Text textKeySequence;

     private KeySequenceText textKeySequenceManager;

     private IntegerFieldEditor textMultiKeyAssistTime;

     private SortedMap tree;

     private void buildCommandAssignmentsTable() {
         tableAssignmentsForCommand.removeAll();
         boolean matchFoundInFirstKeyConfiguration = false;

         for (Iterator iterator = commandAssignments.iterator(); iterator
                 .hasNext();) {
             boolean createTableItem = true;
             CommandAssignment commandAssignment = (CommandAssignment) iterator
                     .next();
             KeySequenceBindingNode.Assignment assignment = commandAssignment.assignment;
             KeySequence keySequence = commandAssignment.keySequence;
             String commandString = null;
             int difference = DIFFERENCE_NONE;

             if (assignment.hasPreferenceCommandIdInFirstKeyConfiguration
                     || assignment.hasPreferenceCommandIdInInheritedKeyConfiguration) {
                 String preferenceCommandId;

                 if (assignment.hasPreferenceCommandIdInFirstKeyConfiguration)
                     preferenceCommandId = assignment.preferenceCommandIdInFirstKeyConfiguration;
                 else
                     preferenceCommandId = assignment.preferenceCommandIdInInheritedKeyConfiguration;

                 if (assignment.hasPluginCommandIdInFirstKeyConfiguration
                         || assignment.hasPluginCommandIdInInheritedKeyConfiguration) {
                     String pluginCommandId;

                     if (assignment.hasPluginCommandIdInFirstKeyConfiguration)
                         pluginCommandId = assignment.pluginCommandIdInFirstKeyConfiguration;
                     else
                         pluginCommandId = assignment.pluginCommandIdInInheritedKeyConfiguration;
                     if (preferenceCommandId != null) {
                         difference = DIFFERENCE_CHANGE;
                         commandString =
                         /* commandUniqueNamesById.get(preferenceCommandId) */
                         keySequence.format() + ""; //$NON-NLS-1$
 } else {
                         difference = DIFFERENCE_MINUS;
                         commandString = /* "Unassigned" */
                         keySequence.format();
                     }

                     if (pluginCommandId != null)
                         commandString += " (was: " //$NON-NLS-1$
 + commandUniqueNamesById.get(pluginCommandId)
                                 + ")"; //$NON-NLS-1$
 else
                         commandString += " (was: " + "Unassigned" + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 } else {
                     if (preferenceCommandId != null) {
                         difference = DIFFERENCE_ADD;
                         commandString =
                         /* commandUniqueNamesById.get(preferenceCommandId) */
                         keySequence.format() + ""; //$NON-NLS-1$
 } else {
                         difference = DIFFERENCE_MINUS;
                         commandString = /* "Unassigned" */
                         keySequence.format();
                     }
                 }
             } else {
                 String pluginCommandId = null;
                 if (assignment.hasPluginCommandIdInFirstKeyConfiguration) {
                     pluginCommandId = assignment.pluginCommandIdInFirstKeyConfiguration;
                     if (pluginCommandId != null) {
                         matchFoundInFirstKeyConfiguration = true;
                     }
                 } else if (!matchFoundInFirstKeyConfiguration) {
                     pluginCommandId = assignment.pluginCommandIdInInheritedKeyConfiguration;
                 } else {
                     createTableItem = false;
                     iterator.remove();
                 }

                 if (pluginCommandId != null) {
                     difference = DIFFERENCE_NONE;
                     commandString =
                     /* commandUniqueNamesById.get(preferenceCommandId) */
                     keySequence.format() + ""; //$NON-NLS-1$
 } else {
                     difference = DIFFERENCE_MINUS;
                     commandString = /* "Unassigned" */
                     keySequence.format();
                 }
             }

             if (createTableItem) {
                 TableItem tableItem = new TableItem(tableAssignmentsForCommand,
                         SWT.NULL);

                 switch (difference) {
                 case DIFFERENCE_ADD:
                     tableItem.setImage(0, IMAGE_PLUS);
                     break;

                 case DIFFERENCE_CHANGE:
                     tableItem.setImage(0, IMAGE_CHANGE);
                     break;

                 case DIFFERENCE_MINUS:
                     tableItem.setImage(0, IMAGE_MINUS);
                     break;

                 case DIFFERENCE_NONE:
                     tableItem.setImage(0, IMAGE_BLANK);
                     break;
                 }

                 String contextId = commandAssignment.contextId;

                 if (contextId == null) {
                     // This should never happen.
 tableItem.setText(1, Util.ZERO_LENGTH_STRING);
                 } else
                     tableItem.setText(1, (String ) contextUniqueNamesById
                             .get(contextId)); //$NON-NLS-1$

                 tableItem.setText(2, commandString);

                 if (difference == DIFFERENCE_MINUS) {
                     tableItem.setForeground(minusColour);
                 }
             }
         }
     }

     private void buildKeySequenceAssignmentsTable() {
         tableAssignmentsForKeySequence.removeAll();
         boolean matchFoundInFirstKeyConfiguration = false;
         
         for (Iterator iterator = keySequenceAssignments.iterator(); iterator
                 .hasNext();) {
             boolean createTableItem = true;
             KeySequenceAssignment keySequenceAssignment = (KeySequenceAssignment) iterator
                     .next();
             KeySequenceBindingNode.Assignment assignment = keySequenceAssignment.assignment;
             String commandString = null;
             int difference = DIFFERENCE_NONE;

             if (assignment.hasPreferenceCommandIdInFirstKeyConfiguration
                     || assignment.hasPreferenceCommandIdInInheritedKeyConfiguration) {
                 String preferenceCommandId;

                 if (assignment.hasPreferenceCommandIdInFirstKeyConfiguration)
                     preferenceCommandId = assignment.preferenceCommandIdInFirstKeyConfiguration;
                 else
                     preferenceCommandId = assignment.preferenceCommandIdInInheritedKeyConfiguration;

                 if (assignment.hasPluginCommandIdInFirstKeyConfiguration
                         || assignment.hasPluginCommandIdInInheritedKeyConfiguration) {
                     String pluginCommandId;

                     if (assignment.hasPluginCommandIdInFirstKeyConfiguration)
                         pluginCommandId = assignment.pluginCommandIdInFirstKeyConfiguration;
                     else
                         pluginCommandId = assignment.pluginCommandIdInInheritedKeyConfiguration;

                     if (preferenceCommandId != null) {
                         difference = DIFFERENCE_CHANGE;
                         commandString = commandUniqueNamesById
                                 .get(preferenceCommandId)
                                 + ""; //$NON-NLS-1$
 } else {
                         difference = DIFFERENCE_MINUS;
                         commandString = "Unassigned"; //$NON-NLS-1$
 }

                     if (pluginCommandId != null)
                         commandString += " (was: " //$NON-NLS-1$
 + commandUniqueNamesById.get(pluginCommandId)
                                 + ")"; //$NON-NLS-1$
 else
                         commandString += " (was: " + "Unassigned" + ")"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
 } else {
                     if (preferenceCommandId != null) {
                         difference = DIFFERENCE_ADD;
                         commandString = commandUniqueNamesById
                                 .get(preferenceCommandId)
                                 + ""; //$NON-NLS-1$
 } else {
                         difference = DIFFERENCE_MINUS;
                         commandString = "Unassigned"; //$NON-NLS-1$
 }
                 }
             } else {
                 String pluginCommandId = null;

                 if (assignment.hasPluginCommandIdInFirstKeyConfiguration) {
                     pluginCommandId = assignment.pluginCommandIdInFirstKeyConfiguration;
                     if (pluginCommandId != null) {
                         matchFoundInFirstKeyConfiguration = true;
                     }
                 } else if (!matchFoundInFirstKeyConfiguration) {
                     pluginCommandId = assignment.pluginCommandIdInInheritedKeyConfiguration;
                 } else {
                     createTableItem = false;
                     iterator.remove();
                 }

                 if (pluginCommandId != null) {
                     difference = DIFFERENCE_NONE;
                     commandString = commandUniqueNamesById.get(pluginCommandId)
                             + ""; //$NON-NLS-1$
 } else {
                     difference = DIFFERENCE_MINUS;
                     commandString = "Unassigned"; //$NON-NLS-1$
 }
             }

             if (createTableItem) {
                 TableItem tableItem = new TableItem(
                         tableAssignmentsForKeySequence, SWT.NULL);

                 switch (difference) {
                 case DIFFERENCE_ADD:
                     tableItem.setImage(0, IMAGE_PLUS);
                     break;

                 case DIFFERENCE_CHANGE:
                     tableItem.setImage(0, IMAGE_CHANGE);
                     break;

                 case DIFFERENCE_MINUS:
                     tableItem.setImage(0, IMAGE_MINUS);
                     break;

                 case DIFFERENCE_NONE:
                     tableItem.setImage(0, IMAGE_BLANK);
                     break;
                 }

                 String contextId = keySequenceAssignment.contextId;

                 if (contextId == null) {
                     // This should never happen.
 tableItem.setText(1, Util.ZERO_LENGTH_STRING);
                 } else {
                     tableItem.setText(1, (String ) contextUniqueNamesById
                             .get(contextId)); //$NON-NLS-1$
 }

                 tableItem.setText(2, commandString);

                 if (difference == DIFFERENCE_MINUS) {
                     tableItem.setForeground(minusColour);
                 }
             }
         }
     }

     private Composite createAdvancedTab(TabFolder parent) {
         GridData gridData = null;

         // The composite for this tab.
 final Composite composite = new Composite(parent, SWT.NULL);
         composite.setLayoutData(new GridData(GridData.FILL_BOTH));

         // The multi-key assist button.
 checkBoxMultiKeyAssist = new Button(composite, SWT.CHECK);
         checkBoxMultiKeyAssist.setText(Util.translateString(RESOURCE_BUNDLE,
                 "checkBoxMultiKeyAssist.Text")); //$NON-NLS-1$
 checkBoxMultiKeyAssist.setToolTipText(Util.translateString(
                 RESOURCE_BUNDLE, "checkBoxMultiKeyAssist.ToolTipText")); //$NON-NLS-1$
 checkBoxMultiKeyAssist.setSelection(getPreferenceStore().getBoolean(
                 IPreferenceConstants.MULTI_KEY_ASSIST));
         gridData = new GridData(GridData.FILL_HORIZONTAL);
         gridData.horizontalSpan = 2;
         checkBoxMultiKeyAssist.setLayoutData(gridData);

         // The multi key assist time.
 final IPreferenceStore store = WorkbenchPlugin.getDefault()
                 .getPreferenceStore();
         textMultiKeyAssistTime = new IntegerFieldEditor(
                 IPreferenceConstants.MULTI_KEY_ASSIST_TIME, Util
                         .translateString(RESOURCE_BUNDLE,
                                 "textMultiKeyAssistTime.Text"), composite); //$NON-NLS-1$
 textMultiKeyAssistTime.setPreferenceStore(store);
         textMultiKeyAssistTime.setPreferencePage(this);
         textMultiKeyAssistTime.setTextLimit(9);
         textMultiKeyAssistTime.setErrorMessage(Util.translateString(
                 RESOURCE_BUNDLE, "textMultiKeyAssistTime.ErrorMessage")); //$NON-NLS-1$
 textMultiKeyAssistTime
                 .setValidateStrategy(StringFieldEditor.VALIDATE_ON_KEY_STROKE);
         textMultiKeyAssistTime.setValidRange(1, Integer.MAX_VALUE);
         textMultiKeyAssistTime.setStringValue(Integer.toString(store
                 .getInt(IPreferenceConstants.MULTI_KEY_ASSIST_TIME)));
         textMultiKeyAssistTime
                 .setPropertyChangeListener(new IPropertyChangeListener() {

                     public void propertyChange(PropertyChangeEvent event) {
                         if (event.getProperty().equals(FieldEditor.IS_VALID))
                                 setValid(textMultiKeyAssistTime.isValid());
                     }
                 });

         // Conigure the layout of the composite.
 final GridLayout gridLayout = new GridLayout();
         gridLayout.marginHeight = 5;
         gridLayout.marginWidth = 5;
         gridLayout.numColumns = 2;
         composite.setLayout(gridLayout);

         return composite;
     }

     private Composite createBasicTab(TabFolder parent) {
         Composite composite = new Composite(parent, SWT.NULL);
         composite.setLayout(new GridLayout());
         GridData gridData = new GridData(GridData.FILL_BOTH);
         composite.setLayoutData(gridData);
         Composite compositeKeyConfiguration = new Composite(composite, SWT.NULL);
         GridLayout gridLayout = new GridLayout();
         gridLayout.numColumns = 3;
         compositeKeyConfiguration.setLayout(gridLayout);
         gridData = new GridData(GridData.FILL_HORIZONTAL);
         compositeKeyConfiguration.setLayoutData(gridData);
         labelKeyConfiguration = new Label(compositeKeyConfiguration, SWT.LEFT);
         labelKeyConfiguration.setText(Util.translateString(RESOURCE_BUNDLE,
                 "labelKeyConfiguration")); //$NON-NLS-1$
 comboKeyConfiguration = new Combo(compositeKeyConfiguration,
                 SWT.READ_ONLY);
         gridData = new GridData();
         gridData.widthHint = 200;
         comboKeyConfiguration.setLayoutData(gridData);

         comboKeyConfiguration.addSelectionListener(new SelectionAdapter() {

             public void widgetSelected(SelectionEvent selectionEvent) {
                 selectedComboKeyConfiguration();
             }
         });

         labelKeyConfigurationExtends = new Label(compositeKeyConfiguration,
                 SWT.LEFT);
         gridData = new GridData(GridData.FILL_HORIZONTAL);
         labelKeyConfigurationExtends.setLayoutData(gridData);
         Control spacer = new Composite(composite, SWT.NULL);
         gridData = new GridData();
         gridData.heightHint = 10;
         gridData.widthHint = 10;
         spacer.setLayoutData(gridData);
         groupCommand = new Group(composite, SWT.SHADOW_NONE);
         gridLayout = new GridLayout();
         gridLayout.numColumns = 3;
         groupCommand.setLayout(gridLayout);
         gridData = new GridData(GridData.FILL_BOTH);
         groupCommand.setLayoutData(gridData);
         groupCommand.setText(Util.translateString(RESOURCE_BUNDLE,
                 "groupCommand")); //$NON-NLS-1$
 labelCategory = new Label(groupCommand, SWT.LEFT);
         gridData = new GridData();
         labelCategory.setLayoutData(gridData);
         labelCategory.setText(Util.translateString(RESOURCE_BUNDLE,
                 "labelCategory")); //$NON-NLS-1$
 comboCategory = new Combo(groupCommand, SWT.READ_ONLY);
         gridData = new GridData();
         gridData.horizontalSpan = 2;
         gridData.widthHint = 200;
         comboCategory.setLayoutData(gridData);

         comboCategory.addSelectionListener(new SelectionAdapter() {

             public void widgetSelected(SelectionEvent selectionEvent) {
                 selectedComboCategory();
             }
         });

         labelCommand = new Label(groupCommand, SWT.LEFT);
         gridData = new GridData();
         labelCommand.setLayoutData(gridData);
         labelCommand.setText(Util.translateString(RESOURCE_BUNDLE,
                 "labelCommand")); //$NON-NLS-1$
 comboCommand = new Combo(groupCommand, SWT.READ_ONLY);
         gridData = new GridData();
         gridData.horizontalSpan = 2;
         gridData.widthHint = 300;
         comboCommand.setLayoutData(gridData);

         comboCommand.addSelectionListener(new SelectionAdapter() {

             public void widgetSelected(SelectionEvent selectionEvent) {
                 selectedComboCommand();
             }
         });

         labelAssignmentsForCommand = new Label(groupCommand, SWT.LEFT);
         gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
         gridData.verticalAlignment = GridData.FILL_VERTICAL;
         labelAssignmentsForCommand.setLayoutData(gridData);
         labelAssignmentsForCommand.setText(Util.translateString(
                 RESOURCE_BUNDLE, "labelAssignmentsForCommand")); //$NON-NLS-1$
 tableAssignmentsForCommand = new Table(groupCommand, SWT.BORDER
                 | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);
         tableAssignmentsForCommand.setHeaderVisible(true);
         gridData = new GridData(GridData.FILL_BOTH);
         gridData.heightHint = 60;
         gridData.horizontalSpan = 2;
         gridData.widthHint = "carbon".equals(SWT.getPlatform()) ? 620 : 520; //$NON-NLS-1$
 tableAssignmentsForCommand.setLayoutData(gridData);
         TableColumn tableColumnDelta = new TableColumn(
                 tableAssignmentsForCommand, SWT.NULL, 0);
         tableColumnDelta.setResizable(false);
         tableColumnDelta.setText(Util.ZERO_LENGTH_STRING);
         tableColumnDelta.setWidth(20);
         TableColumn tableColumnContext = new TableColumn(
                 tableAssignmentsForCommand, SWT.NULL, 1);
         tableColumnContext.setResizable(true);
         tableColumnContext.setText(Util.translateString(RESOURCE_BUNDLE,
                 "tableColumnContext")); //$NON-NLS-1$
 tableColumnContext.pack();
         tableColumnContext.setWidth(200);
         TableColumn tableColumnKeySequence = new TableColumn(
                 tableAssignmentsForCommand, SWT.NULL, 2);
         tableColumnKeySequence.setResizable(true);
         tableColumnKeySequence.setText(Util.translateString(RESOURCE_BUNDLE,
                 "tableColumnKeySequence")); //$NON-NLS-1$
 tableColumnKeySequence.pack();
         tableColumnKeySequence.setWidth(300);

         tableAssignmentsForCommand.addMouseListener(new MouseAdapter() {

             public void mouseDoubleClick(MouseEvent mouseEvent) {
                 doubleClickedAssignmentsForCommand();
             }
         });

         tableAssignmentsForCommand.addSelectionListener(new SelectionAdapter() {

             public void widgetSelected(SelectionEvent selectionEvent) {
                 selectedTableAssignmentsForCommand();
             }
         });

         groupKeySequence = new Group(composite, SWT.SHADOW_NONE);
         gridLayout = new GridLayout();
         gridLayout.numColumns = 4;
         groupKeySequence.setLayout(gridLayout);
         gridData = new GridData(GridData.FILL_BOTH);
         groupKeySequence.setLayoutData(gridData);
         groupKeySequence.setText(Util.translateString(RESOURCE_BUNDLE,
                 "groupKeySequence")); //$NON-NLS-1$
 labelKeySequence = new Label(groupKeySequence, SWT.LEFT);
         gridData = new GridData();
         labelKeySequence.setLayoutData(gridData);
         labelKeySequence.setText(Util.translateString(RESOURCE_BUNDLE,
                 "labelKeySequence")); //$NON-NLS-1$

         // The text widget into which the key strokes will be entered.
 textKeySequence = new Text(groupKeySequence, SWT.BORDER);
         // On MacOS X, this font will be changed by KeySequenceText
 textKeySequence.setFont(groupKeySequence.getFont());
         gridData = new GridData();
         gridData.horizontalSpan = 2;
         gridData.widthHint = 300;
         textKeySequence.setLayoutData(gridData);
         textKeySequence.addModifyListener(new ModifyListener() {

             public void modifyText(ModifyEvent e) {
                 modifiedTextKeySequence();
             }
         });
         textKeySequence.addFocusListener(new FocusListener() {

             /*
              * (non-Javadoc)
              *
              * @see org.eclipse.swt.events.FocusListener#focusGained(org.eclipse.swt.events.FocusEvent)
              */
             public void focusGained(FocusEvent e) {
                 PlatformUI.getWorkbench().getContextSupport()
                         .setKeyFilterEnabled(false);
             }

             /*
              * (non-Javadoc)
              *
              * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent)
              */
             public void focusLost(FocusEvent e) {
                 PlatformUI.getWorkbench().getContextSupport()
                         .setKeyFilterEnabled(true);
             }
         });

         // The manager for the key sequence text widget.
 textKeySequenceManager = new KeySequenceText(textKeySequence);
         textKeySequenceManager.setKeyStrokeLimit(4);

         // Button for adding trapped key strokes
 buttonAddKey = new Button(groupKeySequence, SWT.LEFT | SWT.ARROW);
         buttonAddKey.setToolTipText(Util.translateString(RESOURCE_BUNDLE,
                 "buttonAddKey.ToolTipText")); //$NON-NLS-1$
 gridData = new GridData();
         gridData.heightHint = comboCategory.getTextHeight();
         buttonAddKey.setLayoutData(gridData);
         buttonAddKey.addSelectionListener(new SelectionAdapter() {

             public void widgetSelected(SelectionEvent selectionEvent) {
                 Point buttonLocation = buttonAddKey.getLocation();
                 buttonLocation = groupKeySequence.toDisplay(buttonLocation.x,
                         buttonLocation.y);
                 Point buttonSize = buttonAddKey.getSize();
                 menuButtonAddKey.setLocation(buttonLocation.x, buttonLocation.y
                         + buttonSize.y);
                 menuButtonAddKey.setVisible(true);
             }
         });

         // Arrow buttons aren't normally added to the tab list. Let's fix that.
 Control[] tabStops = groupKeySequence.getTabList();
         ArrayList newTabStops = new ArrayList ();
         for (int i = 0; i < tabStops.length; i++) {
             Control tabStop = tabStops[i];
             newTabStops.add(tabStop);
             if (textKeySequence.equals(tabStop)) {
                 newTabStops.add(buttonAddKey);
             }
         }
         Control[] newTabStopArray = (Control[]) newTabStops
                 .toArray(new Control[newTabStops.size()]);
         groupKeySequence.setTabList(newTabStopArray);

         // Construct the menu to attach to the above button.
 menuButtonAddKey = new Menu(buttonAddKey);
         Iterator trappedKeyItr = KeySequenceText.TRAPPED_KEYS.iterator();
         while (trappedKeyItr.hasNext()) {
             final KeyStroke trappedKey = (KeyStroke) trappedKeyItr.next();
             MenuItem menuItem = new MenuItem(menuButtonAddKey, SWT.PUSH);
             menuItem.setText(trappedKey.format());
             menuItem.addSelectionListener(new SelectionAdapter() {

                 public void widgetSelected(SelectionEvent e) {
                     textKeySequenceManager.insert(trappedKey);
                     textKeySequence.setFocus();
                     textKeySequence
                             .setSelection(textKeySequence.getTextLimit());
                 }
             });
         }

         labelAssignmentsForKeySequence = new Label(groupKeySequence, SWT.LEFT);
         gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
         gridData.verticalAlignment = GridData.FILL_VERTICAL;
         labelAssignmentsForKeySequence.setLayoutData(gridData);
         labelAssignmentsForKeySequence.setText(Util.translateString(
                 RESOURCE_BUNDLE, "labelAssignmentsForKeySequence")); //$NON-NLS-1$
 tableAssignmentsForKeySequence = new Table(groupKeySequence, SWT.BORDER
                 | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);
         tableAssignmentsForKeySequence.setHeaderVisible(true);
         gridData = new GridData(GridData.FILL_BOTH);
         gridData.heightHint = 60;
         gridData.horizontalSpan = 3;
         gridData.widthHint = "carbon".equals(SWT.getPlatform()) ? 620 : 520; //$NON-NLS-1$
 tableAssignmentsForKeySequence.setLayoutData(gridData);
         tableColumnDelta = new TableColumn(tableAssignmentsForKeySequence,
                 SWT.NULL, 0);
         tableColumnDelta.setResizable(false);
         tableColumnDelta.setText(Util.ZERO_LENGTH_STRING);
         tableColumnDelta.setWidth(20);
         tableColumnContext = new TableColumn(tableAssignmentsForKeySequence,
                 SWT.NULL, 1);
         tableColumnContext.setResizable(true);
         tableColumnContext.setText(Util.translateString(RESOURCE_BUNDLE,
                 "tableColumnContext")); //$NON-NLS-1$
 tableColumnContext.pack();
         tableColumnContext.setWidth(200);
         TableColumn tableColumnCommand = new TableColumn(
                 tableAssignmentsForKeySequence, SWT.NULL, 2);
         tableColumnCommand.setResizable(true);
         tableColumnCommand.setText(Util.translateString(RESOURCE_BUNDLE,
                 "tableColumnCommand")); //$NON-NLS-1$
 tableColumnCommand.pack();
         tableColumnCommand.setWidth(300);

         tableAssignmentsForKeySequence.addMouseListener(new MouseAdapter() {

             public void mouseDoubleClick(MouseEvent mouseEvent) {
                 doubleClickedTableAssignmentsForKeySequence();
             }
         });

         tableAssignmentsForKeySequence
                 .addSelectionListener(new SelectionAdapter() {

                     public void widgetSelected(SelectionEvent selectionEvent) {
                         selectedTableAssignmentsForKeySequence();
                     }
                 });

         Composite compositeContext = new Composite(composite, SWT.NULL);
         gridLayout = new GridLayout();
         gridLayout.numColumns = 3;
         compositeContext.setLayout(gridLayout);
         gridData = new GridData(GridData.FILL_HORIZONTAL);
         compositeContext.setLayoutData(gridData);
         labelContext = new Label(compositeContext, SWT.LEFT);
         labelContext.setText(Util.translateString(RESOURCE_BUNDLE,
                 "labelContext")); //$NON-NLS-1$
 comboContext = new Combo(compositeContext, SWT.READ_ONLY);
         gridData = new GridData();
         gridData.widthHint = 250;
         comboContext.setLayoutData(gridData);

         comboContext.addSelectionListener(new SelectionAdapter() {

             public void widgetSelected(SelectionEvent selectionEvent) {
                 selectedComboContext();
             }
         });

         labelContextExtends = new Label(compositeContext, SWT.LEFT);
         gridData = new GridData(GridData.FILL_HORIZONTAL);
         labelContextExtends.setLayoutData(gridData);
         Composite compositeButton = new Composite(composite, SWT.NULL);
         gridLayout = new GridLayout();
         gridLayout.marginHeight = 20;
         gridLayout.marginWidth = 0;
         gridLayout.numColumns = 3;
         compositeButton.setLayout(gridLayout);
         gridData = new GridData();
         compositeButton.setLayoutData(gridData);
         buttonAdd = new Button(compositeButton, SWT.CENTER | SWT.PUSH);
         gridData = new GridData();
         gridData.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
         int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
         buttonAdd.setText(Util.translateString(RESOURCE_BUNDLE, "buttonAdd")); //$NON-NLS-1$
 gridData.widthHint = Math.max(widthHint, buttonAdd.computeSize(
                 SWT.DEFAULT, SWT.DEFAULT, true).x) + 5;
         buttonAdd.setLayoutData(gridData);

         buttonAdd.addSelectionListener(new SelectionAdapter() {

             public void widgetSelected(SelectionEvent selectionEvent) {
                 selectedButtonAdd();
             }
         });

         buttonRemove = new Button(compositeButton, SWT.CENTER | SWT.PUSH);
         gridData = new GridData();
         gridData.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
         widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
         buttonRemove.setText(Util.translateString(RESOURCE_BUNDLE,
                 "buttonRemove")); //$NON-NLS-1$
 gridData.widthHint = Math.max(widthHint, buttonRemove.computeSize(
                 SWT.DEFAULT, SWT.DEFAULT, true).x) + 5;
         buttonRemove.setLayoutData(gridData);

         buttonRemove.addSelectionListener(new SelectionAdapter() {

             public void widgetSelected(SelectionEvent selectionEvent) {
                 selectedButtonRemove();
             }
         });

         buttonRestore = new Button(compositeButton, SWT.CENTER | SWT.PUSH);
         gridData = new GridData();
         gridData.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
         widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
         buttonRestore.setText(Util.translateString(RESOURCE_BUNDLE,
                 "buttonRestore")); //$NON-NLS-1$
 gridData.widthHint = Math.max(widthHint, buttonRestore.computeSize(
                 SWT.DEFAULT, SWT.DEFAULT, true).x) + 5;
         buttonRestore.setLayoutData(gridData);

         buttonRestore.addSelectionListener(new SelectionAdapter() {

             public void widgetSelected(SelectionEvent selectionEvent) {
                 selectedButtonRestore();
             }
         });

         // TODO WorkbenchHelp.setHelp(parent,
 // IHelpContextIds.WORKBENCH_KEY_PREFERENCE_PAGE);
 return composite;
     }

     protected Control createContents(Composite parent) {
         // Initialize the minus colour.
 minusColour = getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
         
         final TabFolder tabFolder = new TabFolder(parent, SWT.NULL);

         // Basic tab
 final TabItem basicTab = new TabItem(tabFolder, SWT.NULL);
         basicTab
                 .setText(Util.translateString(RESOURCE_BUNDLE, "basicTab.Text")); //$NON-NLS-1$
 basicTab.setControl(createBasicTab(tabFolder));

         // Advanced tab
 final TabItem advancedTab = new TabItem(tabFolder, SWT.NULL);
         advancedTab.setText(Util.translateString(RESOURCE_BUNDLE,
                 "advancedTab.Text")); //$NON-NLS-1$
 advancedTab.setControl(createAdvancedTab(tabFolder));

         applyDialogFont(tabFolder);
         return tabFolder;
     }

     protected IPreferenceStore doGetPreferenceStore() {
         return PlatformUI.getWorkbench().getPreferenceStore();
     }

     private void doubleClickedAssignmentsForCommand() {
         update();
     }

     private void doubleClickedTableAssignmentsForKeySequence() {
         update();
     }

     private String getCategoryId() {
         return !commandIdsByCategoryId.containsKey(null)
                 || comboCategory.getSelectionIndex() > 0 ? (String ) categoryIdsByUniqueName
                 .get(comboCategory.getText())
                 : null;
     }

     private String getCommandId() {
         return (String ) commandIdsByUniqueName.get(comboCommand.getText());
     }

     private String getContextId() {
         return comboContext.getSelectionIndex() >= 0 ? (String ) contextIdsByUniqueName
                 .get(comboContext.getText())
                 : null;
     }

     private String getKeyConfigurationId() {
         return comboKeyConfiguration.getSelectionIndex() >= 0 ? (String ) keyConfigurationIdsByUniqueName
                 .get(comboKeyConfiguration.getText())
                 : null;
     }

     private KeySequence getKeySequence() {
         return textKeySequenceManager.getKeySequence();
     }

     public void init(IWorkbench workbench) {
         IWorkbenchContextSupport workbenchContextSupport = workbench
                 .getContextSupport();
         contextManager = workbenchContextSupport.getContextManager();
         // TODO remove blind cast
 commandManager = (MutableCommandManager) workbench.getCommandSupport()
                 .getCommandManager();
         commandAssignments = new TreeSet ();
         keySequenceAssignments = new TreeSet ();
    }

    private void modifiedTextKeySequence() {
        update();
    }

    protected void performDefaults() {
        String activeKeyConfigurationId = getKeyConfigurationId();
        List preferenceKeySequenceBindingDefinitions = new ArrayList ();
        KeySequenceBindingNode.getKeySequenceBindingDefinitions(tree,
                KeySequence.getInstance(), 0,
                preferenceKeySequenceBindingDefinitions);

        if (activeKeyConfigurationId != null
                || !preferenceKeySequenceBindingDefinitions.isEmpty()) {
            final String title = Util.translateString(RESOURCE_BUNDLE,
                    "restoreDefaultsMessageBoxText"); //$NON-NLS-1$
 final String message = Util.translateString(RESOURCE_BUNDLE,
                    "restoreDefaultsMessageBoxMessage"); //$NON-NLS-1$
 final boolean confirmed = MessageDialog.openConfirm(getShell(),
                    title, message);

            if (confirmed) {
                setKeyConfigurationId(IWorkbenchConstants.DEFAULT_ACCELERATOR_CONFIGURATION_ID);
                Iterator iterator = preferenceKeySequenceBindingDefinitions
                        .iterator();

                while (iterator.hasNext()) {
                    KeySequenceBindingDefinition keySequenceBindingDefinition = (KeySequenceBindingDefinition) iterator
                            .next();
                    KeySequenceBindingNode.remove(tree,
                            keySequenceBindingDefinition.getKeySequence(),
                            keySequenceBindingDefinition.getContextId(),
                            keySequenceBindingDefinition
                                    .getKeyConfigurationId(), 0,
                            keySequenceBindingDefinition.getPlatform(),
                            keySequenceBindingDefinition.getLocale(),
                            keySequenceBindingDefinition.getCommandId());
                }
            }
        }

        // Set the defaults on the advanced tab.
 IPreferenceStore store = getPreferenceStore();
        checkBoxMultiKeyAssist.setSelection(store
                .getDefaultBoolean(IPreferenceConstants.MULTI_KEY_ASSIST));
        textMultiKeyAssistTime.setStringValue(Integer.toString(store
                .getDefaultInt(IPreferenceConstants.MULTI_KEY_ASSIST_TIME)));

        update();
    }

    public boolean performOk() {
        List preferenceActiveKeyConfigurationDefinitions = new ArrayList ();
        preferenceActiveKeyConfigurationDefinitions
                .add(new ActiveKeyConfigurationDefinition(
                        getKeyConfigurationId(), null));
        PreferenceCommandRegistry preferenceCommandRegistry = (PreferenceCommandRegistry) commandManager
                .getMutableCommandRegistry();
        preferenceCommandRegistry
                .setActiveKeyConfigurationDefinitions(preferenceActiveKeyConfigurationDefinitions);
        List preferenceKeySequenceBindingDefinitions = new ArrayList ();
        KeySequenceBindingNode.getKeySequenceBindingDefinitions(tree,
                KeySequence.getInstance(), 0,
                preferenceKeySequenceBindingDefinitions);
        preferenceCommandRegistry
                .setKeySequenceBindingDefinitions(preferenceKeySequenceBindingDefinitions);

        try {
            preferenceCommandRegistry.save();
        } catch (IOException eIO) {
            // Do nothing
 }

        // Save the advanced settings.
 IPreferenceStore store = getPreferenceStore();
        store.setValue(IPreferenceConstants.MULTI_KEY_ASSIST,
                checkBoxMultiKeyAssist.getSelection());
        store.setValue(IPreferenceConstants.MULTI_KEY_ASSIST_TIME,
                textMultiKeyAssistTime.getIntValue());
        return super.performOk();
    }

    private void selectAssignmentForCommand(String contextId) {
        if (tableAssignmentsForCommand.getSelectionCount() > 1)
                tableAssignmentsForCommand.deselectAll();

        int i = 0;
        int selection = -1;
        KeySequence keySequence = getKeySequence();

        for (Iterator iterator = commandAssignments.iterator(); iterator
                .hasNext(); i++) {
            CommandAssignment commandAssignment = (CommandAssignment) iterator
                    .next();

            if (Util.equals(contextId, commandAssignment.contextId)
                    && Util.equals(keySequence, commandAssignment.keySequence)) {
                selection = i;
                break;
            }
        }

        if (selection != tableAssignmentsForCommand.getSelectionIndex()) {
            if (selection == -1
                    || selection >= tableAssignmentsForCommand.getItemCount())
                tableAssignmentsForCommand.deselectAll();
            else
                tableAssignmentsForCommand.select(selection);
        }
    }

    private void selectAssignmentForKeySequence(String contextId) {
        if (tableAssignmentsForKeySequence.getSelectionCount() > 1)
                tableAssignmentsForKeySequence.deselectAll();

        int i = 0;
        int selection = -1;

        for (Iterator iterator = keySequenceAssignments.iterator(); iterator
                .hasNext(); i++) {
            KeySequenceAssignment keySequenceAssignment = (KeySequenceAssignment) iterator
                    .next();

            if (Util.equals(contextId, keySequenceAssignment.contextId)) {
                selection = i;
                break;
            }
        }

        if (selection != tableAssignmentsForKeySequence.getSelectionIndex()) {
            if (selection == -1
                    || selection >= tableAssignmentsForKeySequence
                            .getItemCount())
                tableAssignmentsForKeySequence.deselectAll();
            else
                tableAssignmentsForKeySequence.select(selection);
        }
    }

    private void selectedButtonAdd() {
        String commandId = getCommandId();
        String contextId = getContextId();
        String keyConfigurationId = getKeyConfigurationId();
        KeySequence keySequence = getKeySequence();
        KeySequenceBindingNode.remove(tree, keySequence, contextId,
                keyConfigurationId, 0, null, null);
        KeySequenceBindingNode.add(tree, keySequence, contextId,
                keyConfigurationId, 0, null, null, commandId);
        List preferenceKeySequenceBindingDefinitions = new ArrayList ();
        KeySequenceBindingNode.getKeySequenceBindingDefinitions(tree,
                KeySequence.getInstance(), 0,
                preferenceKeySequenceBindingDefinitions);
        update();
    }

    private void selectedButtonRemove() {
        String contextId = getContextId();
        String keyConfigurationId = getKeyConfigurationId();
        KeySequence keySequence = getKeySequence();
        KeySequenceBindingNode.remove(tree, keySequence, contextId,
                keyConfigurationId, 0, null, null);
        KeySequenceBindingNode.add(tree, keySequence, contextId,
                keyConfigurationId, 0, null, null, null);
        List preferenceKeySequenceBindingDefinitions = new ArrayList ();
        KeySequenceBindingNode.getKeySequenceBindingDefinitions(tree,
                KeySequence.getInstance(), 0,
                preferenceKeySequenceBindingDefinitions);
        update();
    }

    private void selectedButtonRestore() {
        String contextId = getContextId();
        String keyConfigurationId = getKeyConfigurationId();
        KeySequence keySequence = getKeySequence();
        KeySequenceBindingNode.remove(tree, keySequence, contextId,
                keyConfigurationId, 0, null, null);
        List preferenceKeySequenceBindingDefinitions = new ArrayList ();
        KeySequenceBindingNode.getKeySequenceBindingDefinitions(tree,
                KeySequence.getInstance(), 0,
                preferenceKeySequenceBindingDefinitions);
        update();
    }

    private void selectedComboCategory() {
        update();
    }

    private void selectedComboCommand() {
        update();
    }

    private void selectedComboContext() {
        update();
    }

    private void selectedComboKeyConfiguration() {
        update();
    }

    private void selectedTableAssignmentsForCommand() {
        int selection = tableAssignmentsForCommand.getSelectionIndex();
        List commandAssignmentsAsList = new ArrayList (commandAssignments);

        if (selection >= 0 && selection < commandAssignmentsAsList.size()
                && tableAssignmentsForCommand.getSelectionCount() == 1) {
            CommandAssignment commandAssignment = (CommandAssignment) commandAssignmentsAsList
                    .get(selection);
            String contextId = commandAssignment.contextId;
            KeySequence keySequence = commandAssignment.keySequence;
            setContextId(contextId);
            setKeySequence(keySequence);
        }

        update();
    }

    private void selectedTableAssignmentsForKeySequence() {
        int selection = tableAssignmentsForKeySequence.getSelectionIndex();
        List keySequenceAssignmentsAsList = new ArrayList (
                keySequenceAssignments);

        if (selection >= 0 && selection < keySequenceAssignmentsAsList.size()
                && tableAssignmentsForKeySequence.getSelectionCount() == 1) {
            KeySequenceAssignment keySequenceAssignment = (KeySequenceAssignment) keySequenceAssignmentsAsList
                    .get(selection);
            String contextId = keySequenceAssignment.contextId;
            setContextId(contextId);
        }

        update();
    }

    private void setAssignmentsForCommand() {
        commandAssignments.clear();
        String commandId = getCommandId();

        for (Iterator iterator = assignmentsByContextIdByKeySequence.entrySet()
                .iterator(); iterator.hasNext();) {
            Map.Entry entry = (Map.Entry ) iterator.next();
            KeySequence keySequence = (KeySequence) entry.getKey();
            Map assignmentsByContextId = (Map ) entry.getValue();

            if (assignmentsByContextId != null)
                    for (Iterator iterator2 = assignmentsByContextId.entrySet()
                            .iterator(); iterator2.hasNext();) {
                        Map.Entry entry2 = (Map.Entry ) iterator2.next();
                        CommandAssignment commandAssignment = new CommandAssignment();
                        commandAssignment.assignment = (KeySequenceBindingNode.Assignment) entry2
                                .getValue();
                        commandAssignment.contextId = (String ) entry2.getKey();
                        commandAssignment.keySequence = keySequence;

                        if (commandAssignment.assignment.contains(commandId))
                                commandAssignments.add(commandAssignment);
                    }
        }

        buildCommandAssignmentsTable();
    }

    private void setAssignmentsForKeySequence() {
        keySequenceAssignments.clear();
        KeySequence keySequence = getKeySequence();
        Map assignmentsByContextId = (Map ) assignmentsByContextIdByKeySequence
                .get(keySequence);

        if (assignmentsByContextId != null)
                for (Iterator iterator = assignmentsByContextId.entrySet()
                        .iterator(); iterator.hasNext();) {
                    Map.Entry entry = (Map.Entry ) iterator.next();
                    KeySequenceAssignment keySequenceAssignment = new KeySequenceAssignment();
                    keySequenceAssignment.assignment = (KeySequenceBindingNode.Assignment) entry
                            .getValue();
                    keySequenceAssignment.contextId = (String ) entry.getKey();
                    keySequenceAssignments.add(keySequenceAssignment);
                }

        buildKeySequenceAssignmentsTable();
    }

    private void setCommandId(String commandId) {
        comboCommand.clearSelection();
        comboCommand.deselectAll();
        String commandUniqueName = (String ) commandUniqueNamesById
                .get(commandId);

        if (commandUniqueName != null) {
            String items[] = comboCommand.getItems();

            for (int i = 0; i < items.length; i++)
                if (commandUniqueName.equals(items[i])) {
                    comboCommand.select(i);
                    break;
                }
        }
    }

    private void setCommandsForCategory() {
        String categoryId = getCategoryId();
        String commandId = getCommandId();
        Set commandIds = (Set ) commandIdsByCategoryId.get(categoryId);
        Map commandIdsByName = new HashMap (commandIdsByUniqueName);
        if (commandIds == null) {
            commandIdsByName = new HashMap ();
        } else {
            commandIdsByName.values().retainAll(commandIds);
        }
        List commandNames = new ArrayList (commandIdsByName.keySet());
        Collections.sort(commandNames, Collator.getInstance());
        comboCommand.setItems((String []) commandNames
                .toArray(new String [commandNames.size()]));
        setCommandId(commandId);

        if (comboCommand.getSelectionIndex() == -1 && !commandNames.isEmpty())
                comboCommand.select(0);
    }

    /**
     * Changes the selected context name in the context combo box. The context
     * selected is either the one matching the identifier provided (if
     * possible), or the default context identifier. If no matching name can be
     * found in the combo, then the first item is selected.
     *
     * @param contextId
     * The context identifier for the context to be selected in the
     * combo box; may be <code>null</code>.
     */
    private void setContextId(String contextId) {
        // Clear the current selection.
 comboContext.clearSelection();
        comboContext.deselectAll();

        // Figure out which name to look for.
 String contextName = (String ) contextUniqueNamesById.get(contextId);
        if (contextName == null) {
            contextName = (String ) contextUniqueNamesById
                    .get(KeySequenceBinding.DEFAULT_CONTEXT_ID);
        }
        if (contextName == null) {
            contextName = Util.ZERO_LENGTH_STRING;
        }

        // Scan the list for the selection we're looking for.
 final String [] items = comboContext.getItems();
        boolean found = false;
        for (int i = 0; i < items.length; i++) {
            if (contextName.equals(items[i])) {
                comboContext.select(i);
                found = true;
                break;
            }
        }

        // If we didn't find an item, then set the first item as selected.
 if ((!found) && (items.length > 0)) {
            comboContext.select(0);
        }
    }

    private void setContextsForCommand() {
        String commandId = getCommandId();
        String contextId = getContextId();
        Map contextIdsByName = new HashMap (contextIdsByUniqueName);

        List contextNames = new ArrayList (contextIdsByName.keySet());
        Collections.sort(contextNames, Collator.getInstance());

        comboContext.setItems((String []) contextNames
                .toArray(new String [contextNames.size()]));
        setContextId(contextId);

        if (comboContext.getSelectionIndex() == -1 && !contextNames.isEmpty())
                comboContext.select(0);
    }

    private void setKeyConfigurationId(String keyConfigurationId) {
        comboKeyConfiguration.clearSelection();
        comboKeyConfiguration.deselectAll();
        String keyConfigurationUniqueName = (String ) keyConfigurationUniqueNamesById
                .get(keyConfigurationId);

        if (keyConfigurationUniqueName != null) {
            String items[] = comboKeyConfiguration.getItems();

            for (int i = 0; i < items.length; i++)
                if (keyConfigurationUniqueName.equals(items[i])) {
                    comboKeyConfiguration.select(i);
                    break;
                }
        }
    }

    private void setKeySequence(KeySequence keySequence) {
        textKeySequenceManager.setKeySequence(keySequence);
    }

    public void setVisible(boolean visible) {
        if (visible == true) {
            Map contextsByName = new HashMap ();

            for (Iterator iterator = contextManager.getDefinedContextIds()
                    .iterator(); iterator.hasNext();) {
                IContext context = contextManager.getContext((String ) iterator
                        .next());

                try {
                    String name = context.getName();
                    Collection contexts = (Collection ) contextsByName.get(name);

                    if (contexts == null) {
                        contexts = new HashSet ();
                        contextsByName.put(name, contexts);
                    }

                    contexts.add(context);
                } catch (org.eclipse.ui.contexts.NotDefinedException eNotDefined) {
                    // Do nothing
 }
            }

            Map categoriesByName = new HashMap ();

            for (Iterator iterator = commandManager.getDefinedCategoryIds()
                    .iterator(); iterator.hasNext();) {
                ICategory category = commandManager
                        .getCategory((String ) iterator.next());

                try {
                    String name = category.getName();
                    Collection categories = (Collection ) categoriesByName
                            .get(name);

                    if (categories == null) {
                        categories = new HashSet ();
                        categoriesByName.put(name, categories);
                    }

                    categories.add(category);
                } catch (org.eclipse.ui.commands.NotDefinedException eNotDefined) {
                    // Do nothing
 }
            }

            Map commandsByName = new HashMap ();

            for (Iterator iterator = commandManager.getDefinedCommandIds()
                    .iterator(); iterator.hasNext();) {
                ICommand command = commandManager.getCommand((String ) iterator
                        .next());

                try {
                    String name = command.getName();
                    Collection commands = (Collection ) commandsByName.get(name);

                    if (commands == null) {
                        commands = new HashSet ();
                        commandsByName.put(name, commands);
                    }

                    commands.add(command);
                } catch (org.eclipse.ui.commands.NotDefinedException eNotDefined) {
                    // Do nothing
 }
            }

            Map keyConfigurationsByName = new HashMap ();

            for (Iterator iterator = commandManager
                    .getDefinedKeyConfigurationIds().iterator(); iterator
                    .hasNext();) {
                IKeyConfiguration keyConfiguration = commandManager
                        .getKeyConfiguration((String ) iterator.next());

                try {
                    String name = keyConfiguration.getName();
                    Collection keyConfigurations = (Collection ) keyConfigurationsByName
                            .get(name);

                    if (keyConfigurations == null) {
                        keyConfigurations = new HashSet ();
                        keyConfigurationsByName.put(name, keyConfigurations);
                    }

                    keyConfigurations.add(keyConfiguration);
                } catch (org.eclipse.ui.commands.NotDefinedException eNotDefined) {
                    // Do nothing
 }
            }

            contextIdsByUniqueName = new HashMap ();
            contextUniqueNamesById = new HashMap ();

            for (Iterator iterator = contextsByName.entrySet().iterator(); iterator
                    .hasNext();) {
                Map.Entry entry = (Map.Entry ) iterator.next();
                String name = (String ) entry.getKey();
                Set contexts = (Set ) entry.getValue();
                Iterator iterator2 = contexts.iterator();

                if (contexts.size() == 1) {
                    IContext context = (IContext) iterator2.next();
                    contextIdsByUniqueName.put(name, context.getId());
                    contextUniqueNamesById.put(context.getId(), name);
                } else
                    while (iterator2.hasNext()) {
                        IContext context = (IContext) iterator2.next();
                        String uniqueName = MessageFormat.format(
                                Util.translateString(RESOURCE_BUNDLE,
                                        "uniqueName"), new Object [] { name, //$NON-NLS-1$
 context.getId()});
                        contextIdsByUniqueName.put(uniqueName, context.getId());
                        contextUniqueNamesById.put(context.getId(), uniqueName);
                    }
            }

            categoryIdsByUniqueName = new HashMap ();
            categoryUniqueNamesById = new HashMap ();

            for (Iterator iterator = categoriesByName.entrySet().iterator(); iterator
                    .hasNext();) {
                Map.Entry entry = (Map.Entry ) iterator.next();
                String name = (String ) entry.getKey();
                Set categories = (Set ) entry.getValue();
                Iterator iterator2 = categories.iterator();

                if (categories.size() == 1) {
                    ICategory category = (ICategory) iterator2.next();
                    categoryIdsByUniqueName.put(name, category.getId());
                    categoryUniqueNamesById.put(category.getId(), name);
                } else
                    while (iterator2.hasNext()) {
                        ICategory category = (ICategory) iterator2.next();
                        String uniqueName = MessageFormat.format(
                                Util.translateString(RESOURCE_BUNDLE,
                                        "uniqueName"), new Object [] { name, //$NON-NLS-1$
 category.getId()});
                        categoryIdsByUniqueName.put(uniqueName, category
                                .getId());
                        categoryUniqueNamesById.put(category.getId(),
                                uniqueName);
                    }
            }

            commandIdsByUniqueName = new HashMap ();
            commandUniqueNamesById = new HashMap ();

            for (Iterator iterator = commandsByName.entrySet().iterator(); iterator
                    .hasNext();) {
                Map.Entry entry = (Map.Entry ) iterator.next();
                String name = (String ) entry.getKey();
                Set commands = (Set ) entry.getValue();
                Iterator iterator2 = commands.iterator();

                if (commands.size() == 1) {
                    ICommand command = (ICommand) iterator2.next();
                    commandIdsByUniqueName.put(name, command.getId());
                    commandUniqueNamesById.put(command.getId(), name);
                } else
                    while (iterator2.hasNext()) {
                        ICommand command = (ICommand) iterator2.next();
                        String uniqueName = MessageFormat.format(
                                Util.translateString(RESOURCE_BUNDLE,
                                        "uniqueName"), new Object [] { name, //$NON-NLS-1$
 command.getId()});
                        commandIdsByUniqueName.put(uniqueName, command.getId());
                        commandUniqueNamesById.put(command.getId(), uniqueName);
                    }
            }

            keyConfigurationIdsByUniqueName = new HashMap ();
            keyConfigurationUniqueNamesById = new HashMap ();

            for (Iterator iterator = keyConfigurationsByName.entrySet()
                    .iterator(); iterator.hasNext();) {
                Map.Entry entry = (Map.Entry ) iterator.next();
                String name = (String ) entry.getKey();
                Set keyConfigurations = (Set ) entry.getValue();
                Iterator iterator2 = keyConfigurations.iterator();

                if (keyConfigurations.size() == 1) {
                    IKeyConfiguration keyConfiguration = (IKeyConfiguration) iterator2
                            .next();
                    keyConfigurationIdsByUniqueName.put(name, keyConfiguration
                            .getId());
                    keyConfigurationUniqueNamesById.put(keyConfiguration
                            .getId(), name);
                } else
                    while (iterator2.hasNext()) {
                        IKeyConfiguration keyConfiguration = (IKeyConfiguration) iterator2
                                .next();
                        String uniqueName = MessageFormat.format(
                                Util.translateString(RESOURCE_BUNDLE,
                                        "uniqueName"), new Object [] { name, //$NON-NLS-1$
 keyConfiguration.getId()});
                        keyConfigurationIdsByUniqueName.put(uniqueName,
                                keyConfiguration.getId());
                        keyConfigurationUniqueNamesById.put(keyConfiguration
                                .getId(), uniqueName);
                    }
            }

            String activeKeyConfigurationId = commandManager
                    .getActiveKeyConfigurationId();
            commandIdsByCategoryId = new HashMap ();

            for (Iterator iterator = commandManager.getDefinedCommandIds()
                    .iterator(); iterator.hasNext();) {
                ICommand command = commandManager.getCommand((String ) iterator
                        .next());

                try {
                    String categoryId = command.getCategoryId();
                    Collection commandIds = (Collection ) commandIdsByCategoryId
                            .get(categoryId);

                    if (commandIds == null) {
                        commandIds = new HashSet ();
                        commandIdsByCategoryId.put(categoryId, commandIds);
                    }

                    commandIds.add(command.getId());
                } catch (org.eclipse.ui.commands.NotDefinedException eNotDefined) {
                    // Do nothing
 }
            }

            ICommandRegistry commandRegistry = commandManager
                    .getCommandRegistry();
            ICommandRegistry mutableCommandRegistry = commandManager
                    .getMutableCommandRegistry();

            List pluginKeySequenceBindingDefinitions = new ArrayList (
                    commandRegistry.getKeySequenceBindingDefinitions());

            for (Iterator iterator = pluginKeySequenceBindingDefinitions
                    .iterator(); iterator.hasNext();) {
                KeySequenceBindingDefinition keySequenceBindingDefinition = (KeySequenceBindingDefinition) iterator
                        .next();
                KeySequence keySequence = keySequenceBindingDefinition
                        .getKeySequence();
                String commandId = keySequenceBindingDefinition.getCommandId();
                String contextId = keySequenceBindingDefinition.getContextId();
                String keyConfigurationId = keySequenceBindingDefinition
                        .getKeyConfigurationId();
                boolean validKeySequence = keySequence != null
                        && MutableCommandManager.validateKeySequence(keySequence);
                boolean validContextId = contextId == null
                        || contextManager.getDefinedContextIds().contains(
                                contextId);
                boolean validCommandId = commandId == null
                        || commandManager.getDefinedCommandIds().contains(
                                commandId);
                boolean validKeyConfigurationId = keyConfigurationId == null
                        || commandManager.getDefinedKeyConfigurationIds()
                                .contains(keyConfigurationId);

                if (!validKeySequence || !validCommandId || !validContextId
                        || !validKeyConfigurationId) iterator.remove();
            }

            List preferenceKeySequenceBindingDefinitions = new ArrayList (
                    mutableCommandRegistry.getKeySequenceBindingDefinitions());

            for (Iterator iterator = preferenceKeySequenceBindingDefinitions
                    .iterator(); iterator.hasNext();) {
                KeySequenceBindingDefinition keySequenceBindingDefinition = (KeySequenceBindingDefinition) iterator
                        .next();
                KeySequence keySequence = keySequenceBindingDefinition
                        .getKeySequence();
                String commandId = keySequenceBindingDefinition.getCommandId();
                String contextId = keySequenceBindingDefinition.getContextId();
                String keyConfigurationId = keySequenceBindingDefinition
                        .getKeyConfigurationId();
                boolean validKeySequence = keySequence != null
                        && MutableCommandManager.validateKeySequence(keySequence);
                boolean validContextId = contextId == null
                        || contextManager.getDefinedContextIds().contains(
                                contextId);
                boolean validCommandId = commandId == null
                        || commandManager.getDefinedCommandIds().contains(
                                commandId);
                boolean validKeyConfigurationId = keyConfigurationId == null
                        || commandManager.getDefinedKeyConfigurationIds()
                                .contains(keyConfigurationId);

                if (!validKeySequence || !validCommandId || !validContextId
                        || !validKeyConfigurationId) iterator.remove();
            }

            tree = new TreeMap ();

            for (Iterator iterator = pluginKeySequenceBindingDefinitions
                    .iterator(); iterator.hasNext();) {
                KeySequenceBindingDefinition keySequenceBindingDefinition = (KeySequenceBindingDefinition) iterator
                        .next();
                KeySequenceBindingNode.add(tree, keySequenceBindingDefinition
                        .getKeySequence(), keySequenceBindingDefinition
                        .getContextId(), keySequenceBindingDefinition
                        .getKeyConfigurationId(), 1,
                        keySequenceBindingDefinition.getPlatform(),
                        keySequenceBindingDefinition.getLocale(),
                        keySequenceBindingDefinition.getCommandId());
            }

            for (Iterator iterator = preferenceKeySequenceBindingDefinitions
                    .iterator(); iterator.hasNext();) {
                KeySequenceBindingDefinition keySequenceBindingDefinition = (KeySequenceBindingDefinition) iterator
                        .next();
                KeySequenceBindingNode.add(tree, keySequenceBindingDefinition
                        .getKeySequence(), keySequenceBindingDefinition
                        .getContextId(), keySequenceBindingDefinition
                        .getKeyConfigurationId(), 0,
                        keySequenceBindingDefinition.getPlatform(),
                        keySequenceBindingDefinition.getLocale(),
                        keySequenceBindingDefinition.getCommandId());
            }

            // TODO?
 //HashSet categoryIdsReferencedByCommandDefinitions = new
 // HashSet();
 //categoryDefinitionsById.keySet().retainAll(categoryIdsReferencedByCommandDefinitions);

            /*
             * TODO rich client platform. simplify UI if possible boolean
             * showCategory = !categoryIdsByUniqueName.isEmpty();
             * labelCategory.setVisible(showCategory);
             * comboCategory.setVisible(showCategory); boolean showContext =
             * !contextIdsByUniqueName.isEmpty();
             * labelContext.setVisible(showContext);
             * comboContext.setVisible(showContext);
             * labelContextExtends.setVisible(showContext); boolean
             * showKeyConfiguration =
             * !keyConfigurationIdsByUniqueName.isEmpty();
             * labelKeyConfiguration.setVisible(showKeyConfiguration);
             * comboKeyConfiguration.setVisible(showKeyConfiguration);
             * labelKeyConfigurationExtends.setVisible(showKeyConfiguration);
             */

            List categoryNames = new ArrayList (categoryIdsByUniqueName.keySet());
            Collections.sort(categoryNames, Collator.getInstance());

            if (commandIdsByCategoryId.containsKey(null))
                    categoryNames.add(0, Util.translateString(RESOURCE_BUNDLE,
                            "other")); //$NON-NLS-1$

            comboCategory.setItems((String []) categoryNames
                    .toArray(new String [categoryNames.size()]));
            comboCategory.clearSelection();
            comboCategory.deselectAll();

            if (commandIdsByCategoryId.containsKey(null)
                    || !categoryNames.isEmpty()) comboCategory.select(0);

            List keyConfigurationNames = new ArrayList (
                    keyConfigurationIdsByUniqueName.keySet());
            Collections.sort(keyConfigurationNames, Collator.getInstance());
            comboKeyConfiguration.setItems((String []) keyConfigurationNames
                    .toArray(new String [keyConfigurationNames.size()]));
            setKeyConfigurationId(activeKeyConfigurationId);
            update();
        }

        super.setVisible(visible);
    }

    private void update() {
        setCommandsForCategory();
        setContextsForCommand();
        String keyConfigurationId = getKeyConfigurationId();
        KeySequence keySequence = getKeySequence();
        String [] activeKeyConfigurationIds = MutableCommandManager
                .extend(commandManager
                        .getKeyConfigurationIds(keyConfigurationId));
        String [] activeLocales = MutableCommandManager.extend(MutableCommandManager.getPath(
                commandManager.getActiveLocale(), MutableCommandManager.SEPARATOR));
        String [] activePlatforms = MutableCommandManager.extend(MutableCommandManager
                .getPath(commandManager.getActivePlatform(),
                        MutableCommandManager.SEPARATOR));
        KeySequenceBindingNode.solve(tree, activeKeyConfigurationIds,
                activePlatforms, activeLocales);
        assignmentsByContextIdByKeySequence = KeySequenceBindingNode
                .getAssignmentsByContextIdKeySequence(tree, KeySequence
                        .getInstance());
        setAssignmentsForKeySequence();
        setAssignmentsForCommand();
        String commandId = getCommandId();
        String contextId = getContextId();
        selectAssignmentForKeySequence(contextId);
        selectAssignmentForCommand(contextId);
        updateLabelKeyConfigurationExtends();
        updateLabelContextExtends();
        labelAssignmentsForKeySequence.setEnabled(keySequence != null
                && !keySequence.getKeyStrokes().isEmpty());
        tableAssignmentsForKeySequence.setEnabled(keySequence != null
                && !keySequence.getKeyStrokes().isEmpty());
        labelAssignmentsForCommand.setEnabled(commandId != null);
        tableAssignmentsForCommand.setEnabled(commandId != null);
        boolean buttonsEnabled = commandId != null && keySequence != null
                && !keySequence.getKeyStrokes().isEmpty();
        boolean buttonAddEnabled = buttonsEnabled;
        boolean buttonRemoveEnabled = buttonsEnabled;
        boolean buttonRestoreEnabled = buttonsEnabled;
        // TODO better button enablement
 buttonAdd.setEnabled(buttonAddEnabled);
        buttonRemove.setEnabled(buttonRemoveEnabled);
        buttonRestore.setEnabled(buttonRestoreEnabled);
    }

    private void updateLabelContextExtends() {
        String contextId = getContextId();

        if (contextId != null) {
            IContext context = contextManager.getContext(getContextId());

            if (context.isDefined()) {
                try {
                    String parentId = context.getParentId();
                    if (parentId != null) {
                        String name = (String ) contextUniqueNamesById
                                .get(parentId);

                        if (name != null) {
                            labelContextExtends.setText(MessageFormat.format(
                                    Util.translateString(RESOURCE_BUNDLE,
                                            "extends"), //$NON-NLS-1$
 new Object [] { name}));

                            return;
                        }
                    }
                } catch (org.eclipse.ui.contexts.NotDefinedException eNotDefined) {
                    // Do nothing
 }
            }
        }

        labelContextExtends.setText(Util.ZERO_LENGTH_STRING);
    }

    private void updateLabelKeyConfigurationExtends() {
        String keyConfigurationId = getKeyConfigurationId();

        if (keyConfigurationId != null) {
            IKeyConfiguration keyConfiguration = commandManager
                    .getKeyConfiguration(keyConfigurationId);

            try {
                String name = (String ) keyConfigurationUniqueNamesById
                        .get(keyConfiguration.getParentId());

                if (name != null) {
                    labelKeyConfigurationExtends.setText(MessageFormat.format(
                            Util.translateString(RESOURCE_BUNDLE, "extends"), //$NON-NLS-1$
 new Object [] { name}));
                    return;
                }
            } catch (org.eclipse.ui.commands.NotDefinedException eNotDefined) {
                // Do nothing
 }
        }

        labelKeyConfigurationExtends.setText(Util.ZERO_LENGTH_STRING);
    }

    /*
     * private void selectedButtonChange() { KeySequence keySequence =
     * getKeySequence(); boolean validKeySequence = keySequence != null &&
     * validateSequence(keySequence); String scopeId = getScopeId(); boolean
     * validScopeId = scopeId != null && contextsDefinitionsById.get(scopeId) !=
     * null; String keyConfigurationId = getKeyConfigurationId(); boolean
     * validKeyConfigurationId = keyConfigurationId != null &&
     * keyConfigurationsById.get(keyConfigurationId) != null; if
     * (validKeySequence && validScopeId && validKeyConfigurationId) { String
     * commandId = null; ISelection selection =
     * treeViewerCommands.getSelection(); if (selection instanceof
     * IStructuredSelection && !selection.isEmpty()) { Object object =
     * ((IStructuredSelection) selection).getFirstElement(); if (object
     * instanceof ICommandDefinition) commandId = ((ICommandDefinition)
     * object).getId(); } CommandRecord commandRecord =
     * getSelectedCommandRecord(); if (commandRecord == null) set(tree,
     * keySequence, scopeId, keyConfigurationId, commandId); else { if
     * (!commandRecord.customSet.isEmpty()) clear(tree, keySequence, scopeId,
     * keyConfigurationId); else set(tree, keySequence, scopeId,
     * keyConfigurationId, null); } commandRecords.clear();
     * buildCommandRecords(tree, commandId, commandRecords);
     * buildTableCommand(); selectTableCommand(scopeId, keyConfigurationId,
     * keySequence); keySequenceRecords.clear(); buildSequenceRecords(tree,
     * keySequence, keySequenceRecords); buildTableKeySequence();
     * selectTableKeySequence(scopeId, keyConfigurationId); update(); } }
     * private void buildTableCommand() { tableSequencesForCommand.removeAll();
     * for (int i = 0; i < commandRecords.size(); i++) { CommandRecord
     * commandRecord = (CommandRecord) commandRecords.get(i); Set customSet =
     * commandRecord.customSet; Set defaultSet = commandRecord.defaultSet; int
     * difference = DIFFERENCE_NONE; //String commandId = null; // // boolean
     * commandConflict = false; String alternateCommandId = null; boolean
     * alternateCommandConflict = false; if (customSet.isEmpty()) { if
     * (defaultSet.contains(commandRecord.command)) { //commandId // // =
     * commandRecord.commandId; commandConflict = commandRecord.defaultConflict; } }
     * else { if (defaultSet.isEmpty()) { if
     * (customSet.contains(commandRecord.command)) { difference =
     * DIFFERENCE_ADD; //commandId = // // commandRecord.commandId; // //
     * commandConflict = commandRecord.customConflict; } } else { if
     * (customSet.contains(commandRecord.command)) { difference =
     * DIFFERENCE_CHANGE; //commandId = // // commandRecord.commandId;
     * commandConflict = commandRecord.customConflict; alternateCommandId =
     * commandRecord.defaultCommand; alternateCommandConflict =
     * commandRecord.defaultConflict; } else { if
     * (defaultSet.contains(commandRecord.command)) { difference =
     * DIFFERENCE_MINUS; //commandId = // // commandRecord.commandId; // //
     * commandConflict = commandRecord.defaultConflict; alternateCommandId =
     * commandRecord.customCommand; alternateCommandConflict =
     * commandRecord.customConflict; } } } } TableItem tableItem = new
     * TableItem(tableSequencesForCommand, SWT.NULL); switch (difference) { case
     * DIFFERENCE_ADD : tableItem.setImage(0, IMAGE_PLUS); break; case
     * DIFFERENCE_CHANGE : tableItem.setImage(0, IMAGE_CHANGE); break; case
     * DIFFERENCE_MINUS : tableItem.setImage(0, IMAGE_MINUS); break; case
     * DIFFERENCE_NONE : tableItem.setImage(0, IMAGE_BLANK); break; }
     * IContextDefinition scope = (IContextDefinition)
     * contextsById.get(commandRecord.scope); tableItem.setText(1, scope != null ?
     * scope.getName() : bracket(commandRecord.scope)); Configuration
     * keyConfiguration = (Configuration)
     * keyConfigurationsById.get(commandRecord.configuration);
     * tableItem.setText(2, keyConfiguration != null ?
     * keyConfiguration.getName() : bracket(commandRecord.configuration));
     * boolean conflict = commandConflict || alternateCommandConflict;
     * StringBuffer stringBuffer = new StringBuffer(); if
     * (commandRecord.sequence != null)
     * stringBuffer.append(KeySupport.formatSequence(commandRecord.sequence,
     * true)); if (commandConflict) stringBuffer.append(SPACE +
     * COMMAND_CONFLICT); String alternateCommandName = null; if
     * (alternateCommandId == null) alternateCommandName = COMMAND_UNDEFINED;
     * else if (alternateCommandId.length() == 0) alternateCommandName =
     * COMMAND_NOTHING; else { ICommandDefinition command = (ICommandDefinition)
     * commandsById.get(alternateCommandId); if (command != null)
     * alternateCommandName = command.getName(); else alternateCommandName =
     * bracket(alternateCommandId); } if (alternateCommandConflict)
     * alternateCommandName += SPACE + COMMAND_CONFLICT;
     * stringBuffer.append(SPACE); if (difference == DIFFERENCE_CHANGE)
     * stringBuffer.append(MessageFormat.format(Util.getString(resourceBundle,
     * "was"), new Object[] { alternateCommandName })); //$NON-NLS-1$ else if
     * (difference == DIFFERENCE_MINUS)
     * stringBuffer.append(MessageFormat.format(Util.getString(resourceBundle,
     * "now"), new Object[] { alternateCommandName })); //$NON-NLS-1$
     * tableItem.setText(3, stringBuffer.toString()); if (difference ==
     * DIFFERENCE_MINUS) { if (conflict) tableItem.setForeground(new
     * Color(getShell().getDisplay(), RGB_CONFLICT_MINUS)); else
     * tableItem.setForeground(new Color(getShell().getDisplay(), RGB_MINUS)); }
     * else if (conflict) tableItem.setForeground(new
     * Color(getShell().getDisplay(), RGB_CONFLICT)); } } private void
     * buildTableKeySequence() { tableCommandsForSequence.removeAll(); for (int
     * i = 0; i < keySequenceRecords.size(); i++) { KeySequenceRecord
     * keySequenceRecord = (KeySequenceRecord) keySequenceRecords.get(i); int
     * difference = DIFFERENCE_NONE; String commandId = null; boolean
     * commandConflict = false; String alternateCommandId = null; boolean
     * alternateCommandConflict = false; if
     * (keySequenceRecord.customSet.isEmpty()) { commandId =
     * keySequenceRecord.defaultCommand; commandConflict =
     * keySequenceRecord.defaultConflict; } else { commandId =
     * keySequenceRecord.customCommand; commandConflict =
     * keySequenceRecord.customConflict; if
     * (keySequenceRecord.defaultSet.isEmpty()) difference = DIFFERENCE_ADD;
     * else { difference = DIFFERENCE_CHANGE; alternateCommandId =
     * keySequenceRecord.defaultCommand; alternateCommandConflict =
     * keySequenceRecord.defaultConflict; } } TableItem tableItem = new
     * TableItem(tableCommandsForSequence, SWT.NULL); switch (difference) { case
     * DIFFERENCE_ADD : tableItem.setImage(0, IMAGE_PLUS); break; case
     * DIFFERENCE_CHANGE : tableItem.setImage(0, IMAGE_CHANGE); break; case
     * DIFFERENCE_MINUS : tableItem.setImage(0, IMAGE_MINUS); break; case
     * DIFFERENCE_NONE : tableItem.setImage(0, IMAGE_BLANK); break; }
     * IContextDefinition scope = (IContextDefinition)
     * contextsById.get(keySequenceRecord.scope); tableItem.setText(1, scope !=
     * null ? scope.getName() : bracket(keySequenceRecord.scope)); Configuration
     * keyConfiguration = (Configuration)
     * keyConfigurationsById.get(keySequenceRecord.configuration);
     * tableItem.setText(2, keyConfiguration != null ?
     * keyConfiguration.getName() : bracket(keySequenceRecord.configuration));
     * boolean conflict = commandConflict || alternateCommandConflict;
     * StringBuffer stringBuffer = new StringBuffer(); String commandName =
     * null; if (commandId == null) commandName = COMMAND_UNDEFINED; else if
     * (commandId.length() == 0) commandName = COMMAND_NOTHING; else {
     * ICommandDefinition command = (ICommandDefinition)
     * commandsById.get(commandId); if (command != null) commandName =
     * command.getName(); else commandName = bracket(commandId); }
     * stringBuffer.append(commandName); if (commandConflict)
     * stringBuffer.append(SPACE + COMMAND_CONFLICT); String
     * alternateCommandName = null; if (alternateCommandId == null)
     * alternateCommandName = COMMAND_UNDEFINED; else if
     * (alternateCommandId.length() == 0) alternateCommandName =
     * COMMAND_NOTHING; else { ICommandDefinition command = (ICommandDefinition)
     * commandsById.get(alternateCommandId); if (command != null)
     * alternateCommandName = command.getName(); else alternateCommandName =
     * bracket(alternateCommandId); } if (alternateCommandConflict)
     * alternateCommandName += SPACE + COMMAND_CONFLICT;
     * stringBuffer.append(SPACE); if (difference == DIFFERENCE_CHANGE)
     * stringBuffer.append(MessageFormat.format(Util.getString(resourceBundle,
     * "was"), new Object[] { alternateCommandName })); //$NON-NLS-1$
     * tableItem.setText(3, stringBuffer.toString()); if (difference ==
     * DIFFERENCE_MINUS) { if (conflict) tableItem.setForeground(new
     * Color(getShell().getDisplay(), RGB_CONFLICT_MINUS)); else
     * tableItem.setForeground(new Color(getShell().getDisplay(), RGB_MINUS)); }
     * else if (conflict) tableItem.setForeground(new
     * Color(getShell().getDisplay(), RGB_CONFLICT)); }
     */
}

